/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.secretaria.saude.listener;

import com.secretaria.saude.dto.ImportacaoTabWinRow;
import com.secretaria.saude.util.DoubleUtil;
import java.util.ArrayList;
import java.util.List;
import org.apache.poi.hssf.eventusermodel.HSSFListener;
import org.apache.poi.hssf.record.BOFRecord;
import org.apache.poi.hssf.record.BlankRecord;
import org.apache.poi.hssf.record.EOFRecord;
import org.apache.poi.hssf.record.FormulaRecord;
import org.apache.poi.hssf.record.LabelSSTRecord;
import org.apache.poi.hssf.record.NumberRecord;
import org.apache.poi.hssf.record.Record;
import org.apache.poi.hssf.record.SSTRecord;
import org.apache.poi.hssf.record.UnicodeString;

/**
 *
 * @author pablo
 */
public class ImportacaoTabWinListener implements HSSFListener {

    private boolean planilhaEncontrada = false;
    private SSTRecord registroEstatico = null;
    private List<ImportacaoTabWinRow> records = new ArrayList<ImportacaoTabWinRow>();
    private ImportacaoTabWinRow row;

    @Override
    public void processRecord(Record record) {

        switch (record.getSid()) {
            case BOFRecord.sid:
                verificarPlanilha(record);
                break;
            case NumberRecord.sid:
                verificarNumero(record);
                break;
            case SSTRecord.sid:
                this.registroEstatico = (SSTRecord) record;
                break;
            case LabelSSTRecord.sid:
                verificarTexto(record);
                break;
            case BlankRecord.sid:
                verificarNovaLinha(record);
                break;
            case EOFRecord.sid:
		adicionaRegistro();
                break;

            case FormulaRecord.sid:
                throw new RuntimeException("Encontrado campo do tipo formula");

        }


    }

    private void verificarNovaLinha(Record record) {
        BlankRecord blankRecord = (BlankRecord) record;
        short coluna = blankRecord.getColumn();
        if (coluna == 0 && this.planilhaEncontrada && blankRecord.getRow() > 0) {
            adicionaRegistro();
            row = new ImportacaoTabWinRow();
        }
    }

    private void verificarTexto(Record record) {
        if (this.planilhaEncontrada) {
            LabelSSTRecord registroRotulo = (LabelSSTRecord) record;
            if (registroRotulo.getRow() > 0) {
                String texto = recuperarString(registroRotulo);
                short coluna = registroRotulo.getColumn();

                switch (coluna) {
                    case 0:
                        adicionaRegistro();                        
                        row = new ImportacaoTabWinRow();
                        row.setCodigoProcedimento(texto.substring(0,10));
                        row.setNomeProcedimento(texto.substring(10));
                        break;
                    case 1:
                        row.setFrequencia(recuperaInteger(texto));
                        break;
                    case 2:
                        row.setValorAprovado(recuperaDouble(texto));
                        break;
                    case 3:
                        row.setQtdApresentada(recuperaInteger(texto));
                        break;
                    case 4:
                        row.setValorApresentado(recuperaDouble(texto));
                        break;
                }
            }
        }
    }

    private void verificarNumero(Record record) {
        if (this.planilhaEncontrada) {
            NumberRecord registroNumerico = (NumberRecord) record;
            if (registroNumerico.getRow() > 0) {
                double valor = registroNumerico.getValue();
                short coluna = registroNumerico.getColumn();
                switch (coluna) {
                    case 1:
                        row.setFrequencia(new Integer((int) valor));
                        break;

                    case 2:
                        row.setValorAprovado(valor);
                        break;

                    case 3:
                        row.setQtdApresentada(new Integer((int) valor));
                        break;

                    case 4:
                        row.setValorApresentado(valor);
                        break;
                }
            }
        }
        
    }

    private void verificarPlanilha(Record record) {
        BOFRecord bof = (BOFRecord) record;
        this.planilhaEncontrada = (bof.getType() == BOFRecord.TYPE_WORKSHEET);
    }

    private void adicionaRegistro() {
        if (row != null) {
            records.add(row);
            row = null;
        }
    }

    private String recuperarString(LabelSSTRecord lrec) {
        UnicodeString stringUnicode = this.registroEstatico.getString(lrec.getSSTIndex());
        return stringUnicode == null ? "" : stringUnicode.getString();
    }

    private Integer recuperaInteger(String texto) {
        try {
            return Integer.parseInt(texto);
        } catch (NumberFormatException e) {
            throw new RuntimeException("A planilha foi gerada com quebra");
        }
    }

    private Double recuperaDouble(String texto) {
        return Double.valueOf(DoubleUtil.converterDouble(texto));
    }

    public List<ImportacaoTabWinRow> getRegistros() {
        return records;
    }
}
